package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.handler.SaveReturnOrderHandler;
import com.ygqh.baby.mapper.YgReturnOrderOffLineMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class YgReturnOrderOffLineServiceImpl implements YgReturnOrderOffLineService {

    @Autowired
    private YgReturnOrderOffLineMapper ygReturnOrderOffLineMapper;
    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgSkuService ygSkuService;
    @Autowired
    private YgReturnOrderDetailOffLineService ygReturnOrderDetailOffLineService;
    @Autowired
    private YgReturnOrderLogService ygReturnOrderLogService;
    @Autowired
    private YgOrderPaymentService ygOrderPaymentService;
    @Autowired
    private YgReturnOrderDetailService ygReturnOrderDetailService;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private YgProductService ygProductService;

    @Override
    public List<YgReturnOrderOffLine> find() {
        YgReturnOrderOffLineExample example = new YgReturnOrderOffLineExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return ygReturnOrderOffLineMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgReturnOrderOffLineExample example = new YgReturnOrderOffLineExample();
        example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
        return ygReturnOrderOffLineMapper.countByExample(example);
    }

    @Override
    public YgReturnOrderOffLine findById(Long id) {
        return ygReturnOrderOffLineMapper.selectByPrimaryKey(id);
    }

    @Override
    public int save(YgReturnOrderOffLine ygReturnOrderOffLine) {
        return ygReturnOrderOffLineMapper.insertSelective(ygReturnOrderOffLine);
    }

    @Override
    public int update(YgReturnOrderOffLine ygReturnOrderOffLine) {
        return ygReturnOrderOffLineMapper.updateByPrimaryKeySelective(ygReturnOrderOffLine);
    }

    @Override
    public ResultSet<YgReturnOrderOffLine> search(QueryInfo queryInfo, Long orderId, Date startDate, Date endDate, String expressCode, String q) {
        List<YgReturnOrderOffLine> list = ygReturnOrderOffLineMapper.selectSuper(queryInfo, orderId, startDate, endDate, expressCode, q);
        int count = ygReturnOrderOffLineMapper.countSuper(orderId, startDate, endDate, expressCode, q);
        ResultSet<YgReturnOrderOffLine> resultSet = new ResultSet<YgReturnOrderOffLine>(count, list);
        return resultSet;
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        YgReturnOrderOffLineExample example = new YgReturnOrderOffLineExample();
        example.createCriteria().andIdIn(Arrays.asList(ids));
        YgReturnOrderOffLine record = new YgReturnOrderOffLine();
        record.setStatus(DataStatus.Delete);

        return ygReturnOrderOffLineMapper.updateByExampleSelective(record, example);
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }

    @Override
    public int saveOrUpdate(YgReturnOrderOffLine ygReturnOrderOffLine) {
        int r = 0;
        if (ygReturnOrderOffLine.getId() != null) {
            r = this.update(ygReturnOrderOffLine);
        } else {
            r = this.save(ygReturnOrderOffLine);
        }
        return r;
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Override
    public Message saveReturnOrder(YgReturnInfoModel infoModel, String returnReason, String imgPaths, YgReturnInfoModel returnInfo, Long userId,
                                   String handler) {
        YgOrder order = ygOrderService.findOrderDetailByOrderId(infoModel.getOrderId());
        if (userId.intValue() != order.getUserId().intValue()) {
            return Message.error("订单有误请重试", null);
        }

        YgReturnOrderOffLine returnOrder = new YgReturnOrderOffLine();
        Long frameCode = ygFrameCodeService.getFrameCode(CodeType.ReOrder, new Date());

        returnOrder.setReturnCode("R" + frameCode);
        returnOrder.setUserId(order.getUserId());
        returnOrder.setOrderId(order.getOrderId());
        returnOrder.setReturnType(ReturnType.Return);
        returnOrder.setReturnPrice(returnInfo.getReturnPrice());
        // 退款多于实际付款，优先退实际支付的
        if (order.getTotalPrice().compareTo(returnInfo.getReturnPrice()) < 0) {
            returnOrder.setAccountPrice(returnInfo.getReturnPrice().subtract(order.getTotalPrice()));
        } else {
            returnOrder.setAccountPrice(new BigDecimal(0));
        }
        returnOrder.setProductPrice(returnInfo.getReturnPrice().subtract(returnOrder.getAccountPrice()));
        returnOrder.setReturnReason(returnReason);
        returnOrder.setReturnImgPath(imgPaths);
        returnOrder.setStatus(DataStatus.Valid);
        returnOrder.setReturnStatus(ReturnStatus.Complete);
        returnOrder.setCreateTime(new Date());
        returnOrder.setRefundPrice(returnOrder.getProductPrice());
        returnOrder.setRefundAccountPrice(returnOrder.getAccountPrice());
        this.save(returnOrder);

        for (ReturnSkuInfo info : infoModel.getSkuInfos()) {
            YgSku sku = ygSkuService.findById(info.getSkuId());
            YgReturnOrderDetailOffLine returnDetail = new YgReturnOrderDetailOffLine();
            returnDetail.setReturnCode(returnOrder.getReturnCode());
            returnDetail.setSkuId(sku.getId());
            returnDetail.setSkuCode(sku.getSkuCode());
            returnDetail.setSizeName(sku.getSizeName());
            returnDetail.setPrice(info.getPrice());
            if (info.getRemark() != null) {
                returnDetail.setRemark(info.getRemark());
            }
            returnDetail.setAmount(info.getQuantity());
            returnDetail.setProductId(sku.getProductId());
            returnDetail.setStatus(DataStatus.Valid);

            returnDetail.setSourceSkuId(sku.getId());
            returnDetail.setSourceSkuCode(sku.getSkuCode());
            returnDetail.setSourceSizeName(sku.getSizeName());
            ygReturnOrderDetailOffLineService.save(returnDetail);
        }
        ygReturnOrderLogService.addReturnOrderLog(returnOrder.getReturnCode(), "线下退货已完成", ReturnStatus.Complete, handler, "");
        return Message.success(returnOrder.getId());
    }

    @Override
    public List<YgReturnOrderOffLine> findDetailByOrderId(Long orderId) {
        YgReturnOrderOffLineExample example = new YgReturnOrderOffLineExample();
        example.createCriteria().andOrderIdEqualTo(orderId).andReturnStatusNotEqualTo(ReturnStatus.Cancel.name());
        List<YgReturnOrderOffLine> list = ygReturnOrderOffLineMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            for (YgReturnOrderOffLine ro : list) {

                List<YgReturnOrderDetailOffLine> details = ygReturnOrderDetailOffLineService.findByReturnCode(ro.getReturnCode());
                ro.setDetailList(details);
            }
        }
        return list;
    }

    @Override
    public OrderInfo4ReturnOff findOrderInfoToOffReturn(Long orderId) {
        return ygReturnOrderOffLineMapper.selectOrderInfoToOffReturn(orderId);
    }

    @Override
    public YgReturnOrderInfoModel findReturnOrderInfo(String returnCode, Long userId) {
        YgReturnOrderInfoModel orderInfo = ygReturnOrderOffLineMapper.selectReturnOrderInfo(returnCode, userId);

        YgOrderPayment payment = ygOrderPaymentService.findByOrderId(orderInfo.getOrderId().toString());
        if (payment != null) {
            orderInfo.setOrderPayCode(payment.getOrderPayCode());
        }
        List<YgReturnOrderLog> scheduleList = ygReturnOrderLogService.getReturnScheduleList(returnCode);
        orderInfo.setLastProgress(scheduleList.get(0).getOperation());
        orderInfo.setLastProgressTime(scheduleList.get(0).getCreateTime());
        if (orderInfo.getReturnType().equals(ReturnType.Change)) {
            List<YgReturnOrderDetialModel> sDetailList = new ArrayList<YgReturnOrderDetialModel>();
            List<YgReturnOrderDetialModel> detailList = new ArrayList<YgReturnOrderDetialModel>();

            Map<Long, List<YgReturnOrderDetialModel>> sourceDetailMap = new LinkedHashMap<Long, List<YgReturnOrderDetialModel>>();
            List<Long> sourceKeys = new ArrayList<Long>();

            Map<Long, List<YgReturnOrderDetialModel>> subDetailMap = new LinkedHashMap<Long, List<YgReturnOrderDetialModel>>();
            List<Long> keys = new ArrayList<Long>();
            for (YgReturnOrderDetialModel detail : orderInfo.getSourceDetailList()) {
                // 退货商品
                List<YgReturnOrderDetialModel> sDetails = null;
                sDetails = sourceDetailMap.get(detail.getSourceSkuId());
                if (sDetails == null) {
                    sDetails = new ArrayList<YgReturnOrderDetialModel>();
                    sourceDetailMap.put(detail.getSourceSkuId(), sDetails);
                    sourceKeys.add(detail.getSourceSkuId());
                }
                sDetails.add(detail);
                // 换成商品
                List<YgReturnOrderDetialModel> subDetails = null;
                subDetails = subDetailMap.get(detail.getSkuId());
                if (subDetails == null) {
                    subDetails = new ArrayList<YgReturnOrderDetialModel>();
                    subDetailMap.put(detail.getSkuId(), subDetails);
                    keys.add(detail.getSkuId());
                }
                subDetails.add(detail);
            }
            for (Long key : sourceKeys) {
                List<YgReturnOrderDetialModel> detialModel = sourceDetailMap.get(key);
                Long amount = 0l;
                for (YgReturnOrderDetialModel detail : detialModel) {
                    amount = amount + detail.getAmount();
                }
                YgReturnOrderDetialModel model = (YgReturnOrderDetialModel) detialModel.get(0).clone();
                model.setAmount(amount);
                model.setSkuId(null);
                model.setSkuCode(null);
                model.setSizeName(null);
                sDetailList.add(model);
            }
            for (Long key : keys) {
                List<YgReturnOrderDetialModel> detialModel = subDetailMap.get(key);
                Long amount = 0l;
                for (YgReturnOrderDetialModel detail : detialModel) {
                    amount = amount + detail.getAmount();
                }
                YgReturnOrderDetialModel model = (YgReturnOrderDetialModel) detialModel.get(0).clone();
                model.setAmount(amount);
                model.setSourceSkuId(null);
                model.setSourceSkuCode(null);
                model.setSourceSizeName(null);
                detailList.add(model);
            }

            orderInfo.setSourceDetailList(sDetailList);
            orderInfo.setDetailList(detailList);
        }
        return orderInfo;
    }

    @Autowired
    private SaveReturnOrderHandler saveReturnOrderHandler;

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Override
    public Message saveReturnOrderV2(YgReturnInfoModel infoModel, ReturnReasonType returnReasonType, String returnReason,
                                     String imgPaths, Long userId, String trueName) {
        return saveReturnOrderHandler.saveReturnOffOrder(infoModel, returnReasonType, returnReason, imgPaths, userId, trueName);
    }

}
